package com.blinddate.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blinddate.context.BaseContext;
import com.blinddate.mapper.UserInfMapper;
import com.blinddate.mapper.UserMapper;
import com.blinddate.pojo.dto.UserInfDto;
import com.blinddate.pojo.entity.User;
import com.blinddate.pojo.entity.UserInf;
import com.blinddate.pojo.result.Result;
import com.blinddate.pojo.vo.*;
import com.blinddate.properties.JwtProperties;
import com.blinddate.service.InterestService;
import com.blinddate.service.UserInfService;
import com.blinddate.service.UserService;
import com.blinddate.utils.AliOssUtil;
import com.blinddate.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
@RequestMapping("/user")
@Api(tags = "用户相关接口")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private UserInfService userInfService;
    @Autowired
    private AliOssUtil aliOssUtil;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private InterestService interestService;
@Autowired
private UserInfMapper userInfMapper;
@Autowired
private UserMapper userMapper;

    //生成的种子最大值
    private static final int MAX = 10000;
    //生成的种子最小值
    private static final int MIN =1;
    //展示的人数
    private static final int COUNT = 10;
    //表示星期6
    private static final int SATURDAY = 6;

    @ApiOperation("用户微信登录")
    @PostMapping("/login")
    public Result wxlogin(String code){
        log.info("微信登录 用户:{}",code);
        User user= userService.wxlogin(code);
        UserLoginVO userLoginVO =new UserLoginVO();
        BeanUtils.copyProperties(user,userLoginVO);
        log.info("{}",user);
        //为微信用户生成jwt令牌
        Map<String,Object> cliams=new HashMap<>();
        cliams.put("userid",user.getId());
        String token= JwtUtil.createJWT(jwtProperties.getUserSecretKey(),jwtProperties.getUserTtl(),cliams);
        userLoginVO.setToken(token);
        return Result.success(userLoginVO);
    }

    @ApiOperation("管理员登录")
    @PostMapping("/admin_login")
    public Result wxAdminLogin(String code){
        log.info("管理员登录 用户:{}",code);
        User user= userService.wxlogin(code);
        UserLoginVO userLoginVO =new UserLoginVO();
        BeanUtils.copyProperties(user,userLoginVO);
        log.info("{}",user);
//        //为微信用户生成jwt令牌
        Map<String,Object> cliams=new HashMap<>();
        cliams.put("userid",user.getId());
        String token= JwtUtil.createJWT(jwtProperties.getUserSecretKey(),jwtProperties.getUserTtl(),cliams);
        userLoginVO.setToken(token);
        log.info("identity:{}",user.getIdentity());
        if (user.getIdentity()==2 || user.getIdentity()==1){
            return Result.success(userLoginVO);
        }
        return Result.error(userLoginVO);
    }

    @ApiOperation("上传微信头像")
    @PostMapping("/upload")
    public Result wxupload(MultipartFile file){
        log.info(file.toString());
        //动态获取文件后缀
        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
        //根据uuid设置文件名
        String s = UUID.randomUUID().toString()+substring;
        try {
            String filePath = aliOssUtil.upload(file.getBytes(), s);
            //添加头像到数据库

            userInfService.wxupload(filePath);

            return Result.success();
        } catch (IOException e) {
            throw new RuntimeException("上传文件模块有异常请查看CommonController类:"+e.getMessage());
        }
    }

    @ApiOperation("获取用户信息列表")
    @GetMapping("/userInf")  //判断时间
    public Result<List<UserInfVO>> userInf(){
        log.info("尝试获取用户列表{}");
        //获取用户信息
        Long userId = BaseContext.getCurrentId();
        UserInf userInf = userInfService.getUserInf(userId);
        //用户还需要显示的数量
        int userGetCount = COUNT;
        //获取当前时间
        LocalDateTime nowDate = LocalDateTime.now();
        //获取当天为一周的星期几
        List<UserInfVO> list = new ArrayList<>();
        //获取今天是星期几
        int weekValue =nowDate.getDayOfWeek().getValue();
        if (weekValue==SATURDAY){
            //获取关注的个数  转换为int 类型\
            int interestCount = interestService.interestCont().intValue();
            list = interestService.list(1,interestCount);
            if (list!=null && list.size()>=COUNT){
                //如果满足要求
                return Result.success(list);
            }
        }
        //不满足要求的话补充用户信息  去重
        userGetCount = COUNT - list.size();

        String getUserRand = userId + "rand";
        Object objetcRand = redisTemplate.opsForValue().get(getUserRand);
        String userRand;
        if (objetcRand==null) {
            Double rand = (Math.random() * (MAX + 1 - MIN)) + MIN;
            userRand = String.format("%.2f",rand);
            //获得到明天的时间差（用秒进行计算）
            Long timeOut = BaseContext.timeOut();
            redisTemplate.opsForValue().set(getUserRand, userRand,BaseContext.timeOut(), TimeUnit.SECONDS);
        }else {
            userRand = objetcRand.toString();
        }

        //获取用户信息
        List<UserInfVO> userInfList = new ArrayList<>();
        log.info("age:{}",userInf.getAge());
        userInfList = userInfService.getUserList(userId,userInf.getGender(),userRand,userGetCount,userInf.getPlace(),userInf.getAge());
        list.addAll(userInfList);
        if (list.size()>=COUNT){
            return Result.success(list);
        }
        userGetCount = COUNT - list.size();
        String[] split = userInf.getPlace().split(" ");
        userInfList = userInfService.getOtherList(userId, userInf.getGender(), userRand, userGetCount, userInf.getPlace(), split[0],userInf.getAge());
        list.addAll(userInfList);
        return Result.success(list);
    }

    @ApiOperation("获取指定用户信息")
    @GetMapping("/useroneInf")
    public Result<UserInfVO> useroneInf(@RequestParam Long getId){
        log.info("获取指定用户信息,参数getId:{}",getId);
        Long userId = BaseContext.getCurrentId();
        UserInfVO oneUser = userInfService.getOneUser(userId, getId);
        if (oneUser!=null){
            return Result.success(oneUser);
        }
        return Result.error("用户id不存在");
    }



    @ApiOperation("提交信息卡")
    @PostMapping("/sub_user_inf")
    public Result subUserInf(@RequestBody UserInfDto userInfDto) throws IOException {
        log.info("提交信息卡,参数userInfDto:{}",userInfDto);
        Integer integer = userInfService.uploaduserInf(userInfDto);
        if (integer == 1){
            //处理临时文件
            String result=userInfDto.getImgSrc();
            if(result==null||result==""){
                deleteimg1();
            }else {
                List<String> list=Arrays.asList(result.split(","));
                deleteimg(list);
            }
            Long userid=BaseContext.getCurrentId();

            log.info("生成用户id为：{}的pdf文件",userid);
            LambdaQueryWrapper<UserInf> lqw=new LambdaQueryWrapper<UserInf>();
            lqw.eq(UserInf::getUserId,userid);
            UserInf userInf=userInfMapper.selectOne(lqw);
            String s = userid.toString()+".pdf";
            String pdfpath=aliOssUtil.pdf(userInf,s);
            LambdaUpdateWrapper<User> wrapper=new LambdaUpdateWrapper<>();
            wrapper.set(User::getPdfPath, pdfpath);
            wrapper.eq(User::getId, userid);
            userService.update(wrapper);

            return Result.success("上传成功");
        }
        return Result.error("上传失败，该用户已经存在");
    }

    @SneakyThrows
    @ApiOperation("更新用户信息卡")
    @PostMapping("/updat_user_inf")
    public Result updateUserInf(@RequestBody UserInf userInf){
        log.info("更新用户信息卡，参数userInf:{}",userInf);
        Long currentId = BaseContext.getCurrentId();
        userInf.setUserId(currentId);
        LambdaUpdateWrapper<UserInf> userInfLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        userInfLambdaUpdateWrapper.eq(UserInf::getUserId,currentId);
        boolean b = userInfService.update(userInf,userInfLambdaUpdateWrapper);
        Long userid=BaseContext.getCurrentId();

        log.info("生成用户id为：{}的pdf文件",userid);
        LambdaQueryWrapper<UserInf> lqw=new LambdaQueryWrapper<UserInf>();
        lqw.eq(UserInf::getUserId,userid);
         userInf=userInfMapper.selectOne(lqw);
        String s = userid.toString()+".pdf";
        String pdfpath=aliOssUtil.pdf(userInf,s);
        if (b){
            String result=userInf.getImgSrc();
            if(result==null||result==""){
                deleteimg1();
            }else {
                List<String> list=Arrays.asList(result.split(","));
                deleteimg(list);
            }

            return Result.success("更新成功");
        }
        return Result.error("更新失败");
    }

    @ApiOperation("获取自己的信息")
    @GetMapping("/get_self_inf")
    public Result<UserInf> getSelfInf(){
        log.info("获取自己的信息");
        Long userId = BaseContext.getCurrentId();
        try {
            UserInf userInf = userInfService.getUserInf(userId);
            return Result.success(userInf);
        }catch (NullPointerException e){
            return Result.error("用户信息未填写");
        }
    }

    @DeleteMapping("/delete_user_inf")
    @ApiOperation("管理员删除用户信息")
    public Result<String> deleteUserInf(@RequestParam Long userId){
        log.info("管理员删除用户信息,参数userId:{}",userId);
        //判断用户权限
        Boolean decide = userService.superAdmin();
        if (!decide){
            return Result.error("用户权限不够");
        }

        Boolean deleteUser = userInfService.deleteUser(userId);
        if (deleteUser){
            return Result.success("用户信息删除成功");
        }
        return Result.error("该用户信息已经不存在");
    }

    @DeleteMapping("delete_self_inf")
    @ApiOperation("用户删除自己的信息")
    public Result<String> deleteSelfInf(){
        log.info("用户删除自己的信息");
        Long userId = BaseContext.getCurrentId();
        Boolean deleteUser = userInfService.deleteUser(userId);
        if (deleteUser){
            return Result.success("用户删除自己信息成功");
        }
        return Result.error("你的账号已经被注销请不要重复注销");
    }



    @PostMapping("/admin_upadte_user_inf")
    @ApiOperation("管理员修改用户的vip权限")
    public Result<String> adminUpdateUserInf(@RequestBody UserVO userVO){//提交用户的信息
        log.info("管理员修改用户的vip权限,参数user:{}",userVO);
        //判断用户权限
        Boolean decide = userService.identityDecide();
        if (!decide){
            return Result.error("用户权限不够");
        }
        User user = User.builder().openId(userVO.getOpenId())
                .id(userVO.getId()).identity(userVO.getIdentity())
                .count(userVO.getCount()).pdfPath(userVO.getPdfPath())
                .greenEndTime(userVO.getGreenEndTime()).greenStartTime(userVO.getGreenStartTime())
                .vipTimeEnd(userVO.getVipTimeEnd()).vipTimeStart(userVO.getVipTimeStart())
                .showEndTime(userVO.getShowEndTime()).showStartTime(userVO.getShowStartTime()).build();
        boolean update = userService.updateById(user);
        if (update){
            return Result.success("用户的信息更改成功");
        }
        return Result.error("用户信息更改失败");
    }

    @ApiOperation("解锁别人的具体信息")
    @PostMapping("/unlock")
    public Result unlock(Long id){
        log.info("解锁别人的具体信息，参数id:{}",id);
        UserInfVO userInfVO=userInfService.unlock(id);
        if(userInfVO==null){
            return Result.error("解锁失败！");
        }
        return Result.success(userInfVO);
    }
    @ApiOperation("获取查看次数")
    @GetMapping("getcounts")
    public Result getcounts(){
        log.info("获取查看次数");
        User user= userService.getUser(BaseContext.getCurrentId());
        int count=user.getCount();
        return Result.success(count);
    }
    @ApiOperation("更新查看次数")
    @PostMapping("/updatecounts")
    public Result upcounts(Integer count){
        log.info("更新查看次数,参数count:{}",count);
        User user= userService.getUser(BaseContext.getCurrentId());
        user.setCount(count);
        userService.update(user);
        return Result.success(count);
    }
    @GetMapping("/judge")
    @ApiOperation("判断用户是否为管理员")
    public Result judge(){
        User user =userService.getUser(BaseContext.getCurrentId());
        return Result.success(user.getIdentity());
    }

    @GetMapping("/admin_get_user_inf")
    @ApiOperation("管理员获取用户信息列表")
    public Result<List<UserInf>> adminGetUserInf(@RequestParam Integer page,@RequestParam Integer size){
        log.info("管理员获取用户信息,参数page:{},size:{}",page,size);
        //判断用户权限
        Boolean decide = userService.identityDecide();
        if (!decide){
            return Result.error("用户权限不够");
        }

        IPage<UserInf> iPage = new Page<>(page,size);
        userInfService.page(iPage);
        List<UserInf> records = iPage.getRecords();
        return Result.success(records);
    }

    @GetMapping("/admin_get_user")
    @ApiOperation("管理员获取用户user表中的信息--不是userInf表中的")
    public Result<User> adminGetUser(Long userId){
        log.info("管理员获取用户user表中的信息--不是userInf表中的,参数userId:{}",userId);
        //判断用户权限
        Boolean decide = userService.identityDecide();
        if (!decide){
            return Result.error("用户权限不够");
        }

        User user = userService.getById(userId);
        if (user!=null){
            return Result.success(user);
        }
        return Result.error("没有该用户的核心数据");
    }
    @GetMapping("/admin_get_userlist")
    @ApiOperation("管理员获取用户user表中的信息分页查询（book为3：未展示的用户（未过期） 4：过期未下架的用户 5：已下架的用户 6：已展示的用户（未过期） ）")
    public Result adminGetUserList(@RequestParam Integer page,@RequestParam Integer size,@RequestParam Integer book ){
        log.info("管理员获取用户user表中的信息--不是userInf表中的,参page:{},size:{}",page,size);
        //判断用户权限
        Boolean decide = userService.identityDecide();
        if (!decide){
            return Result.error("用户权限不够");
        }

        List<User> userList= userService.getUserList(page,size,book);
        if (userList!=null){
            if(book==1){
                List<UserGreenVO>userGreenVOList=new ArrayList<>();
                for (User user : userList) {
                    UserGreenVO userGreenVO=new UserGreenVO();
                    BeanUtils.copyProperties(user,userGreenVO);
                    userGreenVOList.add(userGreenVO);
                }
                return Result.success(userGreenVOList);

            } else if (book==2) {
                List<UserVipVO>userVipVOList=new ArrayList<>();
                for (User user : userList) {
                    UserVipVO userVipVO=new UserVipVO();
                    BeanUtils.copyProperties(user,userVipVO);
                    userVipVOList.add(userVipVO);

                }
                return Result.success(userVipVOList);
            }else {
                List<UserShowVO>userShowVOList=new ArrayList<>();
                for (User user : userList) {
                    UserShowVO userShowVO=new UserShowVO();
                    BeanUtils.copyProperties(user,userShowVO);
                    userShowVOList.add(userShowVO);

                }
                return Result.success(userShowVOList);
            }

        }
        return Result.error("没有用户的核心数据");
    }
    @PostMapping("/admin_change_show_status")
    @ApiOperation("管理员改变用户信息展示的状态(1为上架展示，0为下架)")
    public Result changestatus(Long userId, Integer status){
        log.info("改变用户：{}的信息展示状态为：{}",userId,status);
        Boolean decide = userService.identityDecide();
        if (!decide){
            return Result.error("用户权限不够");
        }
        User user=userService.getUser(userId);
        user.setShowStatus(status);
        userService.update(user);
        return Result.success();
    }

    @GetMapping("admin_get_userInf_byId")
    @ApiOperation("管理员获取用户信息")
    public Result<UserInf> adminGetUserInfById(Long userId){
        log.info("管理员获取用户信息,参数userId:{}",userId);
        //判断用户权限
        Boolean decide = userService.identityDecide();
        if (!decide){
            return Result.error("用户权限不够");
        }

        LambdaQueryWrapper<UserInf> userInfLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfLambdaQueryWrapper.eq(UserInf::getUserId,userId);
        UserInf userInf = userInfService.getOne(userInfLambdaQueryWrapper);
        if (userInf!=null){
            return Result.success(userInf);
        }
        return Result.error("没有该用户信息");

    }


    @GetMapping("/admin_get_sex")
    @ApiOperation("用户性别统计个数统计")
    public Result<SexVO> adminGetSex(@RequestParam Long shopId){//0为都统计 1为统计男性 2为统计女性
        log.info("用户性别统计个数统计");
        //判断用户权限
        Boolean decide = userService.superAdmin();
        if (!decide){
            return Result.error("用户权限不够");
        }
        SexVO sexVO = new SexVO();
        long count = userInfService.count();
        sexVO.setTotal(count);
        //统计男性
        LambdaQueryWrapper<UserInf> maleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        maleLambdaQueryWrapper.eq(UserInf::getGender,1);
        long male = userInfService.count(maleLambdaQueryWrapper);
        sexVO.setMale(male);
        //统计女性
        LambdaQueryWrapper<UserInf> femaleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        femaleLambdaQueryWrapper.eq(UserInf::getGender,2);
        long female = userInfService.count(femaleLambdaQueryWrapper);
        sexVO.setFemale(female);
        return Result.success(sexVO);
    }

    @GetMapping("/admin_get_age")
    @ApiOperation("对年龄进行统计")
    public Result<List<AgeVO>> adminGetAge(@RequestParam Integer ageStart,@RequestParam Integer ageEnd,@RequestParam Integer ageSpan){//年龄跨度
        log.info("对年龄进行统计,参数ageStart:{},ageEnd:{},ageSpan:{}",ageStart,ageEnd,ageSpan);
        //判断用户权限
        Boolean decide = userService.superAdmin();
        if (!decide){
            return Result.error("用户权限不够");
        }

        List<AgeVO> list = new ArrayList<>();
        int i;
        for (i=ageStart;i<=ageEnd;i+=ageSpan){
            Integer ageRange = i+ageSpan;
            if (ageRange<=ageEnd){
                LambdaQueryWrapper<UserInf> userInfLambdaQueryWrapper = new LambdaQueryWrapper<>();
                userInfLambdaQueryWrapper.gt(UserInf::getAge,i).le(UserInf::getAge,ageRange);
                long ageCount = userInfService.count(userInfLambdaQueryWrapper);
                String ageString = i + "岁到" + ageRange + "岁";
                AgeVO ageVO = new AgeVO();
                ageVO.setAgeString(ageString);
                ageVO.setAgeCount(ageCount);
                list.add(ageVO);
            }
        }
        i = i - ageSpan;
        if (i != ageEnd){
            LambdaQueryWrapper<UserInf> userInfLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userInfLambdaQueryWrapper.gt(UserInf::getAge,i).le(UserInf::getAge,ageEnd);
            long ageCount = userInfService.count(userInfLambdaQueryWrapper);
            String ageString = i + "岁到" + ageEnd + "岁";
            AgeVO ageVO = new AgeVO();
            ageVO.setAgeString(ageString);
            ageVO.setAgeCount(ageCount);
            list.add(ageVO);
        }
        return Result.success(list);
    }

    /**
     * 删除oss文件
     * @param
     */
    public void deleteimg(List<String> list){
        String key="user"+BaseContext.getCurrentId();
        List<String> list1= (List<String>) redisTemplate.opsForValue().get(key);
        if(list1==null){
            return;
        }
        log.info("{}",list1);
        for (String obj : list) {
            if (list1.contains(obj)) {
                list1.remove(obj);
            }
        }
        log.info("{}",list);
        log.info("删除的文件：{}",list1);
        aliOssUtil.delete(list1);
        redisTemplate.delete(key);
    }
    public void deleteimg1(){
        String key="user"+BaseContext.getCurrentId();
        List<String> list1= (List<String>) redisTemplate.opsForValue().get(key);
        if(list1==null){
            return;
        }
        log.info("删除的文件：{}",list1);
        aliOssUtil.delete(list1);
        redisTemplate.delete(key);
    }

}
